using System;
using System.IO;
using System.Reflection;
using ZoneFiveSoftware.Common.Data;

namespace FilteredStatistics.Controller
{
    class MapOverlayPlugin
    {
        private MapOverlayPlugin()
        {
        }

        protected void Initialize()
        {
            try
            {
                DetectMethodsAndClasses();
                m_PluginInstalled = true;
            }
            catch (Exception e)
            {
                m_PluginInstalled = false;
                throw e;
            }
        }

        private void DetectMethodsAndClasses()
        {
            foreach (Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (loadedAssembly.FullName.StartsWith("MapOverlayPlugin"))
                {
                    Type dotRacingControllerType = loadedAssembly.GetType("OldManBiking.MapOverlayPlugin.Controller.DotRacingController");

                    if (dotRacingControllerType != null)
                    {
                        PropertyInfo instanceProperty = dotRacingControllerType.GetProperty("Instance");

                        if (instanceProperty != null)
                        {
                            MethodInfo highlightMethod = dotRacingControllerType.GetMethod("HighlightTimeRanges", new Type[] { typeof(IValueRangeSeries<DateTime>) });
                            PropertyInfo highlightEnabledGetter = dotRacingControllerType.GetProperty("HighlightingEnabled");

                            m_ControllerInstance = instanceProperty.GetGetMethod().Invoke(null, null);

                            if (highlightMethod != null)
                            {
                                m_HighlightMethod = highlightMethod;
                            }

                            if (highlightEnabledGetter != null && highlightEnabledGetter.CanRead &&
                                highlightEnabledGetter.PropertyType == typeof(bool))
                            {
                                m_HighlightEnabledGetter = highlightEnabledGetter;
                            }
                        }
                    }
                }
            }
        }

        public void HighlightTimeRanges(IValueRangeSeries<DateTime> ranges)
        {
            if (IsPluginInstalled && IsHighlightFunctionAvailable)
            {
                m_HighlightMethod.Invoke(m_ControllerInstance, new object[] { ranges });
            }
        }

        public static MapOverlayPlugin Instance
        {
            get
            {
                if (m_Instance == null)
                {
                    m_Instance = new MapOverlayPlugin();
                    m_Instance.Initialize();
                }

                return m_Instance;
            }
        }

        public bool IsPluginInstalled
        {
            get { return m_PluginInstalled; }
        }

        public bool IsHighlightFunctionAvailable
        {
            get { return m_HighlightMethod != null; }
        }

        public bool IsHighlightEnabledGetterAvailable
        {
            get { return m_HighlightEnabledGetter != null; }
        }

        public bool IsHighlightEnabled
        {
            get
            {
                if (IsPluginInstalled && IsHighlightEnabledGetterAvailable)
                {
                    return (bool)m_HighlightEnabledGetter.GetValue(m_ControllerInstance, null);
                }

                return false;
            }
        }

        private static MapOverlayPlugin m_Instance = null;
        private bool m_PluginInstalled = false;
        private object m_ControllerInstance = null;
        private MethodInfo m_HighlightMethod = null;
        private PropertyInfo m_HighlightEnabledGetter = null;
    }
}
